using System;

namespace BepuPhysics.Constraints
{
    /// <summary>
    /// 将类型标记为与特定批处理关联的约束的说明。
    /// </summary>
    /// <remarks>
    /// 请注意,一个批处理可能有多个与其相关联的描述类型,每个类型都可能提供不同的属性或转换逻辑子集。
    /// </remarks>
    /// <typeparam name="TDescription">描述对象的类型。</typeparam>
    public interface IConstraintDescription<TDescription>
        where TDescription : unmanaged, IConstraintDescription<TDescription>
    {
        /// <summary>
        /// 更改给定位置的批处理保留内存,以匹配给定的描述。
        /// </summary>
        /// <param name="Batch">要修改的批次。</param>
        /// <param name="bundleIndex">目标约束捆绑的索引。</param>
        /// <param name="innerIndex">目标约束在其捆绑包中的索引。</param>
        void ApplyDescription(ref TypeBatch batch, int bundleIndex, int innerIndex);


        /// <summary>
        /// 在给定位置从批处理保存的内存创建说明。
        /// </summary>
        /// <param name="Batch">要读取的批。</param>
        /// <param name="bundleIndex">源约束捆绑的索引。</param>
        /// <param name="innerIndex">源约束在其捆绑包中的索引。</param>
        /// <param name="description">约束的说明。</param>
        void BuildDescription(ref TypeBatch batch, int bundleIndex, int innerIndex, out TDescription description);

        /// <summary>
        /// 获取这是其说明的约束的类型ID。
        /// </summary>
        int ConstraintTypeId { get; }
        /// <summary>
        /// 获取包含描述的约束的Batch类型的类型。
        /// </summary>
        Type TypeProcessorType { get; }
    }

    /// <summary>
    /// 将类型标记为一体约束描述。
    /// </summary>
    /// <typeparam name="TDescription">描述的类型。</typeparam>
    /// <remarks>This and the other body-count aware interfaces exist to give the compiler a way to report errors when using Solver.Add with different body counts.</remarks>
    public interface IOneBodyConstraintDescription<TDescription> : IConstraintDescription<TDescription> where TDescription : unmanaged, IOneBodyConstraintDescription<TDescription>
    {
    }

    /// <summary>
    /// 将类型标记为两个主体约束描述。
    /// </summary>
    /// <typeparam name="TDescription">描述的类型。</typeparam>
    /// <remarks>This and the other body-count aware interfaces exist to give the compiler a way to report errors when using Solver.Add with different body counts.</remarks>
    public interface ITwoBodyConstraintDescription<TDescription> : IConstraintDescription<TDescription> where TDescription : unmanaged, ITwoBodyConstraintDescription<TDescription>
    {
    }

    /// <summary>
    /// 将类型标记为三体约束描述。
    /// </summary>
    /// <typeparam name="TDescription">描述的类型。</typeparam>
    /// <remarks>This and the other body-count aware interfaces exist to give the compiler a way to report errors when using Solver.Add with different body counts.</remarks>
    public interface IThreeBodyConstraintDescription<TDescription> : IConstraintDescription<TDescription> where TDescription : unmanaged, IThreeBodyConstraintDescription<TDescription>
    {
    }

    /// <summary>
    /// 将类型标记为四体约束描述。
    /// </summary>
    /// <typeparam name="TDescription">描述的类型。</typeparam>
    /// <remarks>This and the other body-count aware interfaces exist to give the compiler a way to report errors when using Solver.Add with different body counts.</remarks>
    public interface IFourBodyConstraintDescription<TDescription> : IConstraintDescription<TDescription> where TDescription : unmanaged, IFourBodyConstraintDescription<TDescription>
    {
    }
}
